package com.lanhai.fnstore.dispatch;

import org.apache.log4j.Logger;

import com.lanhai.fnstore.Tools;
import com.lanhai.fnstore.cache.AgvCache;
import com.lanhai.fnstore.cache.AgvItem;
import com.lanhai.fnstore.cache.AgvNextTransEnum;
import com.lanhai.fnstore.cache.MountCache;
import com.lanhai.fnstore.cache.ParkCache;
import com.lanhai.fnstore.cache.ParkItem;
import com.lanhai.fnstore.cache.StationGroupCache;
import com.lanhai.fnstore.log.LogData;
import com.lanhai.fnstore.log.LogQueue;
import com.lanhai.fnstore.push.MsgData;
import com.lanhai.fnstore.push.MsgQueue; 
import com.lanhai.fnstore.queue.StationEventUnit; 
import com.lanhai.fnstore.savestate.StateData;
import com.lanhai.fnstore.savestate.StateQueue;
import com.lanhai.fnstore.thirdpart.StationData;
import com.lanhai.fnstore.thirdpart.StationInterface;
import com.lanhai.fnstore.thirdpart.StationResolveFactory;

/**
 * 对接设备指令处理
 * 
 * @author virus408
 *
 */
public class StationResolve {
	private static final Logger logger = Logger.getLogger(StationResolve.class);
	
	
	public static void Resolve(StationEventUnit unit) {
		// 先拿停泊点
		String cmdSign  = ParkCache.getCmdSignByStation(unit.getIp() );
		 

		// 解析到的对象
		StationInterface station = StationResolveFactory.getStationResolve(cmdSign);
		if (station == null) {
			logger.error(String.format("无法解析指令为【%s】的数据", cmdSign));
			return;
		}
			

		StationData sdata = station.resoleveData(unit.getData());
		if (sdata == null){
			logger.error(String.format("解析数据失败【%s】,IP【%s】",Tools.byte2HexStr(unit.getData()) ,unit.getIp()));
			return;
		}
		
		ParkItem park=ParkCache.getParkByStation(unit.getIp(), sdata.getTag(),  sdata.getLine());
		if(park==null) {
			logger.error(String.format("错误的点位：IP【%s】,线别【%d】",unit.getIp() ,sdata.getLine()));
			return;
		}

		switch (sdata.getEventType()) {
		case AllowLeave: 	
			logger.info(String.format("机台IP【%s】，允许小车离开",unit.getIp()));
			StateQueue.Push(new StateData(1,park.getParkName(),"允许AGV离开")); 
			Log(sdata,unit.getIp());
			 
			// 通知小车离开
			AgvItem agv = AgvCache.getAgvByPark(park.getParkNo());
			if (agv != null) {
				AgvCache.updateNextTrans(agv.getAgvId(), AgvNextTransEnum.None);
				// 回退主路
				AgvResolve.AgvToRoad(agv, 0);
				MountCache.setTransing(agv.getAgvId(), false);
			}

			// 清零
			logger.info(String.format("向机台IP【%s】发送清零指令",unit.getIp()));
			MsgData s1 = new MsgData(park.getStationIP(), park.getStationPort());
			s1.setData(station.clear(park.getLine()));
			s1.setRemark("数据清0");
			MsgQueue.Push(park.getLine(), s1);
		  
			break;
		case AllowTrans:
			//允许传输， 
			logger.info(String.format("机台IP【%s】，允许传输",unit.getIp()));
			StateQueue.Push(new StateData(1,park.getParkName(),"传输中")); 
			Log(sdata,unit.getIp());
		 
			
			AgvItem tagv = AgvCache.getAgvByPark(park.getParkNo());
			if(tagv!=null) {
				if(tagv.getNextTrans()==AgvNextTransEnum.DownIn) {
					byte[] agvcmd=AgvCmd.transDown(tagv.getAgvId(), true);
					PushToAgv(tagv,agvcmd,"下层收货"); 
				}else if(tagv.getNextTrans()==AgvNextTransEnum.DownOut) {
					byte[] agvcmd=AgvCmd.transDown(tagv.getAgvId(), false);
					PushToAgv(tagv,agvcmd,"下层发货"); 
				}else if(tagv.getNextTrans()==AgvNextTransEnum.UpIn) {
					byte[] agvcmd=AgvCmd.transUp(tagv.getAgvId(), true);
					PushToAgv(tagv,agvcmd,"上层收货"); 
				}else if(tagv.getNextTrans()==AgvNextTransEnum.UpOut) {
					byte[] agvcmd=AgvCmd.transUp(tagv.getAgvId(), false);
					PushToAgv(tagv,agvcmd,"上层发货"); 
				} else if(tagv.getNextTrans()==AgvNextTransEnum.DownLeftIn) {
					
				} else if(tagv.getNextTrans()==AgvNextTransEnum.DownLeftOut) {
					
				}
			}
			break;
		case Error:
			//设备异常
			//1.机台不可用
			StationGroupCache.updateError(park.getParkNo());
			//2.对应的机台不可传输(空料）
			 ParkCache.updateStationMount(unit.getIp(),  sdata.getLine(),false,
					 false,0,0);
			break;
		case Info:
			logger.info(String.format("机台IP【%s】，更新装货情况:【%s】",unit.getIp(),sdata.mountString()));
			StateQueue.Push(new StateData(1,park.getParkName(),"待分配")); 
			// 更新装卸情况 
			 ParkCache.updateStationMount(unit.getIp(),  sdata.getLine(), sdata.isNeedIn(),
					sdata.isNeedOut(),sdata.getInNum(),sdata.getOutNum());
		 
			 Log(sdata,unit.getIp());
			 
			break;
		default:
			break;

		}

	}
	
	/**
	 * 生成日志并写进队列里
	 * @param data
	 * @param ip
	 */
	static void Log(StationData data,String ip) {
		LogData logobj=LogData.fromStation(data, ip);
		LogQueue.Push(logobj);
	}
	
	static void PushToAgv(AgvItem agv,byte[] data,String remark) {
		MsgData s1 = new MsgData(agv.getIP(), agv.getParkNo());
		s1.setData(data);
		s1.setRemark(remark); 
		s1.setAgvId(agv.getAgvId());
		MsgQueue.Push(0,s1);
	}
}
